#pragma once

#include "..\include\ioctl.h"
#include "..\include\ifc_ldev.h"
#include "..\include\e2010cmd.h"
#include "DynamicLibrary.h"
#include "ThreadClient.h"
#include "LCardPtr.h"
#include "JeolSource.h"

// LCard E20-10 rev.B
class CAdcDevice : public IJeolSource
{
private:

	enum { BLOCKS = 2 };
	typedef SHORT SAMPLE;

	CDynamicLibrary m_Library;
	typedef IDaqLDevice * (* PCREATEINSTANCE) (ULONG);
	const PCREATEINSTANCE CreateInstance;

	CLCardPtr<IDaqLDevice> m_pDevice;

	ADC_PAR_1 m_AdcParams;

	SAMPLE *   m_pData[BLOCKS];
	PULONG_PTR m_pCurrSample;
	SIZE_T     m_nCurrBlock;
	SIZE_T     m_nBlockSamples;
	double     m_fPeriod;

	inline SIZE_T GetCurrBlock(void) const
	{
		ULONG_PTR nCurrSample = 0;
		::InterlockedExchangePointer((void**)&nCurrSample, (void**)*m_pCurrSample);

		const SIZE_T nCurrBlock = nCurrSample / m_nBlockSamples;

		if ( nCurrBlock >= BLOCKS )
		{
			TRACE(_T("\nAchtung!!! block = %d/%d sample=%p/%x\n\n"), nCurrBlock, BLOCKS, nCurrSample, m_nBlockSamples);
		}
		return nCurrBlock % BLOCKS;
	}

	// PDATAREADY_ROUTINE m_pfnDataReady;
	// PVOID m_pContext;
	IDataReceiver * m_pDataReceiver;

#ifdef THROUGH_DUMP
	HANDLE m_hThroughDump;
#endif

private:

	CWorkerThread<> m_WorkerThread;

	HRESULT OnTimer(DWORD_PTR dwParam);
	CTimerClient < CAdcDevice > m_TimerClient;

public:

	CAdcDevice(void);
	virtual ~CAdcDevice(void);

public: // IJeolSource

	virtual BOOL Open(const void * nSlot);
	virtual void Close(void);

	virtual BOOL Start(IDataReceiver * pDataReceiver);
	virtual void Stop(void);
};
